Best JavaScript code snippet using playwright-internal
CSSMetadata.js
Source:CSSMetadata.js
1/*2 * Copyright (C) 2010 Nikita Vasilyev. All rights reserved.3 * Copyright (C) 2010 Joseph Pecoraro. All rights reserved.4 * Copyright (C) 2010 Google Inc. All rights reserved.5 *6 * Redistribution and use in source and binary forms, with or without7 * modification, are permitted provided that the following conditions are8 * met:9 *10 * * Redistributions of source code must retain the above copyright11 * notice, this list of conditions and the following disclaimer.12 * * Redistributions in binary form must reproduce the above13 * copyright notice, this list of conditions and the following disclaimer14 * in the documentation and/or other materials provided with the15 * distribution.16 * * Neither the name of Google Inc. nor the names of its17 * contributors may be used to endorse or promote products derived from18 * this software without specific prior written permission.19 *20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31 */32import * as Common from '../common/common.js';33import * as SupportedCSSProperties from '../generated/SupportedCSSProperties.js';34/**35 * @unrestricted36 */37export class CSSMetadata {38 /**39 * @param {!Array.<!CSSPropertyDefinition>} properties40 * @param {!Map<string, string>} aliasesFor41 */42 constructor(properties, aliasesFor) {43 this._values = /** !Array.<string> */ ([]);44 /** @type {!Map<string, !Array<string>>} */45 this._longhands = new Map();46 /** @type {!Map<string, !Array<string>>} */47 this._shorthands = new Map();48 /** @type {!Set<string>} */49 this._inherited = new Set();50 /** @type {!Set<string>} */51 this._svgProperties = new Set();52 /** @type {!Map<string, !Array<string>>} */53 this._propertyValues = new Map();54 /** @type {!Map<string, string>} */55 this._aliasesFor = aliasesFor;56 for (let i = 0; i < properties.length; ++i) {57 const property = properties[i];58 const propertyName = property.name;59 if (!CSS.supports(propertyName, 'initial')) {60 continue;61 }62 this._values.push(propertyName);63 if (property.inherited) {64 this._inherited.add(propertyName);65 }66 if (property.svg) {67 this._svgProperties.add(propertyName);68 }69 const longhands = properties[i].longhands;70 if (longhands) {71 this._longhands.set(propertyName, longhands);72 for (let j = 0; j < longhands.length; ++j) {73 const longhandName = longhands[j];74 let shorthands = this._shorthands.get(longhandName);75 if (!shorthands) {76 shorthands = [];77 this._shorthands.set(longhandName, shorthands);78 }79 shorthands.push(propertyName);80 }81 }82 }83 this._values.sort(CSSMetadata._sortPrefixesToEnd);84 this._valuesSet = new Set(this._values);85 // Reads in auto-generated property names and values from blink/public/renderer/core/css/css_properties.json586 // treats _generatedPropertyValues as basis87 const propertyValueSets = new Map();88 for (const [propertyName, basisValueObj] of Object.entries(SupportedCSSProperties.generatedPropertyValues)) {89 propertyValueSets.set(propertyName, new Set(basisValueObj.values));90 }91 // and add manually maintained map of extra prop-value pairs92 for (const [propertyName, extraValueObj] of Object.entries(_extraPropertyValues)) {93 if (propertyValueSets.has(propertyName)) {94 propertyValueSets.get(propertyName).addAll(extraValueObj.values);95 } else {96 propertyValueSets.set(propertyName, new Set(extraValueObj.values));97 }98 }99 // finally add common keywords to value sets and convert property values100 // into arrays since callers expect arrays101 for (const [propertyName, values] of propertyValueSets) {102 for (const commonKeyword of CommonKeywords) {103 if (!values.has(commonKeyword) && CSS.supports(propertyName, commonKeyword)) {104 values.add(commonKeyword);105 }106 }107 this._propertyValues.set(propertyName, [...values]);108 }109 /** @type {!Array<string>} */110 this._nameValuePresets = [];111 /** @type {!Array<string>} */112 this._nameValuePresetsIncludingSVG = [];113 for (const name of this._valuesSet) {114 const values = this._specificPropertyValues(name)115 .filter(value => CSS.supports(name, value))116 .sort(CSSMetadata._sortPrefixesToEnd);117 const presets = values.map(value => `${name}: ${value}`);118 if (!this.isSVGProperty(name)) {119 this._nameValuePresets.push(...presets);120 }121 this._nameValuePresetsIncludingSVG.push(...presets);122 }123 }124 /**125 * @param {string} a126 * @param {string} b127 */128 static _sortPrefixesToEnd(a, b) {129 const aIsPrefixed = a.startsWith('-webkit-');130 const bIsPrefixed = b.startsWith('-webkit-');131 if (aIsPrefixed && !bIsPrefixed) {132 return 1;133 }134 if (!aIsPrefixed && bIsPrefixed) {135 return -1;136 }137 return a < b ? -1 : (a > b ? 1 : 0);138 }139 /**140 * @return {!Array<string>}141 */142 allProperties() {143 return this._values;144 }145 /**146 * @param {boolean=} includeSVG147 * @return {!Array<string>}148 */149 nameValuePresets(includeSVG) {150 return includeSVG ? this._nameValuePresetsIncludingSVG : this._nameValuePresets;151 }152 /**153 * @param {string} name154 * @return {boolean}155 */156 isSVGProperty(name) {157 name = name.toLowerCase();158 return this._svgProperties.has(name);159 }160 /**161 * @param {string} shorthand162 * @return {?Array.<string>}163 */164 longhands(shorthand) {165 return this._longhands.get(shorthand) || null;166 }167 /**168 * @param {string} longhand169 * @return {?Array.<string>}170 */171 shorthands(longhand) {172 return this._shorthands.get(longhand) || null;173 }174 /**175 * @param {string} propertyName176 * @return {boolean}177 */178 isColorAwareProperty(propertyName) {179 return !!_colorAwareProperties.has(propertyName.toLowerCase()) || this.isCustomProperty(propertyName.toLowerCase());180 }181 /**182 * @param {string} propertyName183 * @return {boolean}184 */185 isGridAreaDefiningProperty(propertyName) {186 propertyName = propertyName.toLowerCase();187 return propertyName === 'grid' || propertyName === 'grid-template' || propertyName === 'grid-template-areas';188 }189 /**190 * @param {string} propertyName191 * @return {boolean}192 */193 isLengthProperty(propertyName) {194 propertyName = propertyName.toLowerCase();195 if (propertyName === 'line-height') {196 return false;197 }198 return _distanceProperties.has(propertyName) || propertyName.startsWith('margin') ||199 propertyName.startsWith('padding') || propertyName.indexOf('width') !== -1 ||200 propertyName.indexOf('height') !== -1;201 }202 /**203 * @param {string} propertyName204 * @return {boolean}205 */206 isBezierAwareProperty(propertyName) {207 propertyName = propertyName.toLowerCase();208 return !!_bezierAwareProperties.has(propertyName) || this.isCustomProperty(propertyName);209 }210 /**211 * @param {string} propertyName212 * @return {boolean}213 */214 isCustomProperty(propertyName) {215 return propertyName.startsWith('--');216 }217 /**218 * @param {string} propertyName219 * @return {boolean}220 */221 isShadowProperty(propertyName) {222 propertyName = propertyName.toLowerCase();223 return propertyName === 'box-shadow' || propertyName === 'text-shadow' || propertyName === '-webkit-box-shadow';224 }225 /**226 * @param {string} propertyName227 * @return {boolean}228 */229 isStringProperty(propertyName) {230 propertyName = propertyName.toLowerCase();231 // TODO(crbug.com/1033910): Generalize this to all CSS properties232 // that accept <string> values.233 return propertyName === 'content';234 }235 /**236 * @param {string} name237 * @return {string}238 */239 canonicalPropertyName(name) {240 if (this.isCustomProperty(name)) {241 return name;242 }243 name = name.toLowerCase();244 const aliasFor = this._aliasesFor.get(name);245 if (aliasFor) {246 return aliasFor;247 }248 if (!name || name.length < 9 || name.charAt(0) !== '-') {249 return name;250 }251 const match = name.match(/(?:-webkit-)(.+)/);252 if (!match || !this._valuesSet.has(match[1])) {253 return name;254 }255 return match[1];256 }257 /**258 * @param {string} propertyName259 * @return {boolean}260 */261 isCSSPropertyName(propertyName) {262 propertyName = propertyName.toLowerCase();263 if (propertyName.startsWith('-moz-') || propertyName.startsWith('-o-') || propertyName.startsWith('-webkit-') ||264 propertyName.startsWith('-ms-')) {265 return true;266 }267 return this._valuesSet.has(propertyName);268 }269 /**270 * @param {string} propertyName271 * @return {boolean}272 */273 isPropertyInherited(propertyName) {274 propertyName = propertyName.toLowerCase();275 return propertyName.startsWith('--') || this._inherited.has(this.canonicalPropertyName(propertyName)) ||276 this._inherited.has(propertyName);277 }278 /**279 * @param {string} propertyName280 * @return {!Array<string>}281 */282 _specificPropertyValues(propertyName) {283 const unprefixedName = propertyName.replace(/^-webkit-/, '');284 const propertyValues = this._propertyValues;285 // _propertyValues acts like cache; missing properties are added with possible common keywords286 let keywords = propertyValues.get(propertyName) || propertyValues.get(unprefixedName);287 if (!keywords) {288 keywords = [];289 for (const commonKeyword of CommonKeywords) {290 if (CSS.supports(propertyName, commonKeyword)) {291 keywords.push(commonKeyword);292 }293 }294 propertyValues.set(propertyName, keywords);295 }296 return keywords;297 }298 /**299 * @param {string} propertyName300 * @return {!Array<string>}301 */302 propertyValues(propertyName) {303 const acceptedKeywords = ['inherit', 'initial', 'unset'];304 propertyName = propertyName.toLowerCase();305 acceptedKeywords.push(...this._specificPropertyValues(propertyName));306 if (this.isColorAwareProperty(propertyName)) {307 acceptedKeywords.push('currentColor');308 for (const color in Common.Color.Nicknames) {309 acceptedKeywords.push(color);310 }311 }312 return acceptedKeywords.sort(CSSMetadata._sortPrefixesToEnd);313 }314 /**315 * @param {string} property316 * @return {number}317 */318 propertyUsageWeight(property) {319 return Weight[property] || Weight[this.canonicalPropertyName(property)] || 0;320 }321 /**322 * @param {string} key323 * @param {string} value324 * @return {?{text: string, startColumn: number, endColumn: number}}325 */326 getValuePreset(key, value) {327 const values = _valuePresets.get(key);328 let text = values ? values.get(value) : null;329 if (!text) {330 return null;331 }332 let startColumn = text.length;333 let endColumn = text.length;334 if (text) {335 startColumn = text.indexOf('|');336 endColumn = text.lastIndexOf('|');337 endColumn = startColumn === endColumn ? endColumn : endColumn - 1;338 text = text.replace(/\|/g, '');339 }340 return {text, startColumn, endColumn};341 }342}343export const VariableRegex = /(var\(--.*?\))/g;344export const URLRegex = /url\(\s*('.+?'|".+?"|[^)]+)\s*\)/g;345/**346 * Matches an instance of a grid area 'row' definition.347 * 'grid-template-areas', e.g.348 * "a a ."349 *350 * 'grid', 'grid-template', e.g.351 * [track-name] "a a ." minmax(50px, auto) [track-name]352 */353export const GridAreaRowRegex = /((?:\[[\w\- ]+\]\s*)*(?:"[^"]+"|'[^']+'))[^'"\[]*\[?[^'"\[]*/;354/**355 * @return {!CSSMetadata}356 */357export function cssMetadata() {358 if (!CSSMetadata._instance) {359 CSSMetadata._instance =360 new CSSMetadata(SupportedCSSProperties.generatedProperties, SupportedCSSProperties.generatedAliasesFor);361 }362 return CSSMetadata._instance;363}364/**365 * The pipe character '|' indicates where text selection should be set.366 */367const _imageValuePresetMap = new Map([368 ['linear-gradient', 'linear-gradient(|45deg, black, transparent|)'],369 ['radial-gradient', 'radial-gradient(|black, transparent|)'],370 ['repeating-linear-gradient', 'repeating-linear-gradient(|45deg, black, transparent 100px|)'],371 ['repeating-radial-gradient', 'repeating-radial-gradient(|black, transparent 100px|)'],372 ['url', 'url(||)'],373]);374const _valuePresets = new Map([375 [376 'filter', new Map([377 ['blur', 'blur(|1px|)'],378 ['brightness', 'brightness(|0.5|)'],379 ['contrast', 'contrast(|0.5|)'],380 ['drop-shadow', 'drop-shadow(|2px 4px 6px black|)'],381 ['grayscale', 'grayscale(|1|)'],382 ['hue-rotate', 'hue-rotate(|45deg|)'],383 ['invert', 'invert(|1|)'],384 ['opacity', 'opacity(|0.5|)'],385 ['saturate', 'saturate(|0.5|)'],386 ['sepia', 'sepia(|1|)'],387 ['url', 'url(||)'],388 ])389 ],390 ['background', _imageValuePresetMap], ['background-image', _imageValuePresetMap],391 ['-webkit-mask-image', _imageValuePresetMap],392 [393 'transform', new Map([394 ['scale', 'scale(|1.5|)'],395 ['scaleX', 'scaleX(|1.5|)'],396 ['scaleY', 'scaleY(|1.5|)'],397 ['scale3d', 'scale3d(|1.5, 1.5, 1.5|)'],398 ['rotate', 'rotate(|45deg|)'],399 ['rotateX', 'rotateX(|45deg|)'],400 ['rotateY', 'rotateY(|45deg|)'],401 ['rotateZ', 'rotateZ(|45deg|)'],402 ['rotate3d', 'rotate3d(|1, 1, 1, 45deg|)'],403 ['skew', 'skew(|10deg, 10deg|)'],404 ['skewX', 'skewX(|10deg|)'],405 ['skewY', 'skewY(|10deg|)'],406 ['translate', 'translate(|10px, 10px|)'],407 ['translateX', 'translateX(|10px|)'],408 ['translateY', 'translateY(|10px|)'],409 ['translateZ', 'translateZ(|10px|)'],410 ['translate3d', 'translate3d(|10px, 10px, 10px|)'],411 ['matrix', 'matrix(|1, 0, 0, 1, 0, 0|)'],412 ['matrix3d', 'matrix3d(|1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1|)'],413 ['perspective', 'perspective(|10px|)']414 ])415 ]416]);417const _distanceProperties = new Set([418 'background-position', 'border-spacing', 'bottom', 'font-size', 'height', 'left', 'letter-spacing', 'max-height',419 'max-width', 'min-height', 'min-width', 'right', 'text-indent', 'top', 'width', 'word-spacing', 'grid-row-gap',420 'grid-column-gap', 'row-gap'421]);422const _bezierAwareProperties = new Set([423 'animation', 'animation-timing-function', 'transition', 'transition-timing-function', '-webkit-animation',424 '-webkit-animation-timing-function', '-webkit-transition', '-webkit-transition-timing-function'425]);426const _colorAwareProperties = new Set([427 'backdrop-filter',428 'background',429 'background-color',430 'background-image',431 'border',432 'border-color',433 'border-image',434 'border-image-source',435 'border-bottom',436 'border-bottom-color',437 'border-left',438 'border-left-color',439 'border-right',440 'border-right-color',441 'border-top',442 'border-top-color',443 'box-shadow',444 'caret-color',445 'color',446 'column-rule',447 'column-rule-color',448 'fill',449 'list-style-image',450 'outline',451 'outline-color',452 'stroke',453 'text-decoration-color',454 'text-shadow',455 '-webkit-border-after',456 '-webkit-border-after-color',457 '-webkit-border-before',458 '-webkit-border-before-color',459 '-webkit-border-end',460 '-webkit-border-end-color',461 '-webkit-border-start',462 '-webkit-border-start-color',463 '-webkit-box-reflect',464 '-webkit-box-shadow',465 '-webkit-column-rule-color',466 '-webkit-filter',467 '-webkit-mask',468 '-webkit-mask-box-image',469 '-webkit-mask-box-image-source',470 '-webkit-mask-image',471 '-webkit-tap-highlight-color',472 '-webkit-text-decoration-color',473 '-webkit-text-emphasis',474 '-webkit-text-emphasis-color',475 '-webkit-text-fill-color',476 '-webkit-text-stroke',477 '-webkit-text-stroke-color'478]);479// manually maintained list of property values to add into autocomplete list480const _extraPropertyValues = {481 'background-repeat': {values: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round']},482 'content': {values: ['normal', 'close-quote', 'no-close-quote', 'no-open-quote', 'open-quote']},483 'baseline-shift': {values: ['baseline']},484 'max-height': {values: ['min-content', 'max-content', '-webkit-fill-available', 'fit-content']},485 'box-shadow': {values: ['inset']},486 '-webkit-writing-mode': {values: ['horizontal-tb', 'vertical-rl', 'vertical-lr']},487 'writing-mode': {values: ['lr', 'rl', 'tb', 'lr-tb', 'rl-tb', 'tb-rl']},488 'page-break-inside': {values: ['avoid']},489 'cursor': {values: ['-webkit-zoom-in', '-webkit-zoom-out', '-webkit-grab', '-webkit-grabbing']},490 'border-width': {values: ['medium', 'thick', 'thin']},491 'border-style': {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},492 'size': {values: ['a3', 'a4', 'a5', 'b4', 'b5', 'landscape', 'ledger', 'legal', 'letter', 'portrait']},493 'overflow': {values: ['hidden', 'visible', 'overlay', 'scroll']},494 'overscroll-behavior': {values: ['contain']},495 'text-rendering': {values: ['optimizeSpeed', 'optimizeLegibility', 'geometricPrecision']},496 'text-align': {values: ['-webkit-auto', '-webkit-match-parent']},497 'color-interpolation': {values: ['sRGB', 'linearRGB']},498 'word-wrap': {values: ['normal', 'break-word']},499 'font-weight': {values: ['100', '200', '300', '400', '500', '600', '700', '800', '900']},500 '-webkit-text-emphasis': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame']},501 'color-rendering': {values: ['optimizeSpeed', 'optimizeQuality']},502 '-webkit-text-combine': {values: ['horizontal']},503 'text-orientation': {values: ['sideways-right']},504 'outline': {505 values: ['inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin']506 },507 'font': {508 values: [509 'caption', 'icon', 'menu', 'message-box', 'small-caption', '-webkit-mini-control', '-webkit-small-control',510 '-webkit-control', 'status-bar'511 ]512 },513 'dominant-baseline': {values: ['text-before-edge', 'text-after-edge', 'use-script', 'no-change', 'reset-size']},514 '-webkit-text-emphasis-position': {values: ['over', 'under']},515 'alignment-baseline': {values: ['before-edge', 'after-edge', 'text-before-edge', 'text-after-edge', 'hanging']},516 'page-break-before': {values: ['left', 'right', 'always', 'avoid']},517 'border-image': {values: ['repeat', 'stretch', 'space', 'round']},518 'text-decoration':519 {values: ['blink', 'line-through', 'overline', 'underline', 'wavy', 'double', 'solid', 'dashed', 'dotted']},520 'font-family':521 {values: ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace', '-webkit-body', '-webkit-pictograph']},522 'zoom': {values: ['normal']},523 'max-width': {values: ['min-content', 'max-content', '-webkit-fill-available', 'fit-content']},524 '-webkit-font-smoothing': {values: ['antialiased', 'subpixel-antialiased']},525 'border': {526 values: [527 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'528 ]529 },530 'font-variant': {531 values: [532 'small-caps',533 'normal',534 'common-ligatures',535 'no-common-ligatures',536 'discretionary-ligatures',537 'no-discretionary-ligatures',538 'historical-ligatures',539 'no-historical-ligatures',540 'contextual',541 'no-contextual',542 'all-small-caps',543 'petite-caps',544 'all-petite-caps',545 'unicase',546 'titling-caps',547 'lining-nums',548 'oldstyle-nums',549 'proportional-nums',550 'tabular-nums',551 'diagonal-fractions',552 'stacked-fractions',553 'ordinal',554 'slashed-zero',555 'jis78',556 'jis83',557 'jis90',558 'jis04',559 'simplified',560 'traditional',561 'full-width',562 'proportional-width',563 'ruby'564 ]565 },566 'vertical-align': {values: ['top', 'bottom', '-webkit-baseline-middle']},567 'page-break-after': {values: ['left', 'right', 'always', 'avoid']},568 '-webkit-text-emphasis-style': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame']},569 'transform': {570 values: [571 'scale', 'scaleX', 'scaleY', 'scale3d', 'rotate', 'rotateX', 'rotateY',572 'rotateZ', 'rotate3d', 'skew', 'skewX', 'skewY', 'translate', 'translateX',573 'translateY', 'translateZ', 'translate3d', 'matrix', 'matrix3d', 'perspective'574 ]575 },576 'align-content': {577 values: [578 'normal', 'baseline', 'space-between', 'space-around', 'space-evenly', 'stretch', 'center', 'start', 'end',579 'flex-start', 'flex-end'580 ]581 },582 'justify-content': {583 values: [584 'normal', 'space-between', 'space-around', 'space-evenly', 'stretch', 'center', 'start', 'end', 'flex-start',585 'flex-end', 'left', 'right'586 ]587 },588 'place-content': {589 values: [590 'normal', 'space-between', 'space-around', 'space-evenly', 'stretch', 'center', 'start', 'end', 'flex-start',591 'flex-end', 'baseline'592 ]593 },594 'align-items': {595 values:596 ['normal', 'stretch', 'baseline', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end']597 },598 'justify-items': {599 values: [600 'normal', 'stretch', 'baseline', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end',601 'left', 'right', 'legacy'602 ]603 },604 'place-items': {605 values:606 ['normal', 'stretch', 'baseline', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end']607 },608 'align-self': {609 values:610 ['normal', 'stretch', 'baseline', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end']611 },612 'justify-self': {613 values: [614 'normal', 'stretch', 'baseline', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end',615 'left', 'right'616 ]617 },618 'place-self': {619 values:620 ['normal', 'stretch', 'baseline', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end']621 },622 'perspective-origin': {values: ['left', 'center', 'right', 'top', 'bottom']},623 'transform-origin': {values: ['left', 'center', 'right', 'top', 'bottom']},624 'transition-timing-function': {values: ['cubic-bezier', 'steps']},625 'animation-timing-function': {values: ['cubic-bezier', 'steps']},626 '-webkit-backface-visibility': {values: ['visible', 'hidden']},627 '-webkit-column-break-after': {values: ['always', 'avoid']},628 '-webkit-column-break-before': {values: ['always', 'avoid']},629 '-webkit-column-break-inside': {values: ['avoid']},630 '-webkit-column-span': {values: ['all']},631 '-webkit-column-gap': {values: ['normal']},632 'filter': {633 values: [634 'url', 'blur', 'brightness', 'contrast', 'drop-shadow', 'grayscale', 'hue-rotate', 'invert', 'opacity',635 'saturate', 'sepia'636 ]637 },638 'mix-blend-mode': {values: ['unset']},639 'background-blend-mode': {values: ['unset']},640 'grid-template-columns': {values: ['min-content', 'max-content']},641 'grid-template-rows': {values: ['min-content', 'max-content']},642 'grid-auto-flow': {values: ['dense']},643 'background': {644 values: [645 'repeat',646 'repeat-x',647 'repeat-y',648 'no-repeat',649 'top',650 'bottom',651 'left',652 'right',653 'center',654 'fixed',655 'local',656 'scroll',657 'space',658 'round',659 'border-box',660 'content-box',661 'padding-box',662 'linear-gradient',663 'radial-gradient',664 'repeating-linear-gradient',665 'repeating-radial-gradient',666 'url'667 ]668 },669 'background-image':670 {values: ['linear-gradient', 'radial-gradient', 'repeating-linear-gradient', 'repeating-radial-gradient', 'url']},671 'background-position': {values: ['top', 'bottom', 'left', 'right', 'center']},672 'background-position-x': {values: ['left', 'right', 'center']},673 'background-position-y': {values: ['top', 'bottom', 'center']},674 'background-repeat-x': {values: ['repeat', 'no-repeat']},675 'background-repeat-y': {values: ['repeat', 'no-repeat']},676 'border-bottom': {677 values: [678 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'679 ]680 },681 'border-left': {682 values: [683 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'684 ]685 },686 'border-right': {687 values: [688 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'689 ]690 },691 'border-top': {692 values: [693 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'694 ]695 },696 'buffered-rendering': {values: ['static', 'dynamic']},697 'color-interpolation-filters': {values: ['srgb', 'linearrgb']},698 'column-rule': {699 values: [700 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'701 ]702 },703 'flex-flow': {values: ['nowrap', 'row', 'row-reverse', 'column', 'column-reverse', 'wrap', 'wrap-reverse']},704 'height': {values: ['-webkit-fill-available']},705 'inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},706 'list-style': {707 values: [708 'outside',709 'inside',710 'disc',711 'circle',712 'square',713 'decimal',714 'decimal-leading-zero',715 'arabic-indic',716 'bengali',717 'cambodian',718 'khmer',719 'devanagari',720 'gujarati',721 'gurmukhi',722 'kannada',723 'lao',724 'malayalam',725 'mongolian',726 'myanmar',727 'oriya',728 'persian',729 'urdu',730 'telugu',731 'tibetan',732 'thai',733 'lower-roman',734 'upper-roman',735 'lower-greek',736 'lower-alpha',737 'lower-latin',738 'upper-alpha',739 'upper-latin',740 'cjk-earthly-branch',741 'cjk-heavenly-stem',742 'ethiopic-halehame',743 'ethiopic-halehame-am',744 'ethiopic-halehame-ti-er',745 'ethiopic-halehame-ti-et',746 'hangul',747 'hangul-consonant',748 'korean-hangul-formal',749 'korean-hanja-formal',750 'korean-hanja-informal',751 'hebrew',752 'armenian',753 'lower-armenian',754 'upper-armenian',755 'georgian',756 'cjk-ideographic',757 'simp-chinese-formal',758 'simp-chinese-informal',759 'trad-chinese-formal',760 'trad-chinese-informal',761 'hiragana',762 'katakana',763 'hiragana-iroha',764 'katakana-iroha'765 ]766 },767 'max-block-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},768 'max-inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},769 'min-block-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},770 'min-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},771 'min-inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},772 'min-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},773 'object-position': {values: ['top', 'bottom', 'left', 'right', 'center']},774 'shape-outside': {values: ['border-box', 'content-box', 'padding-box', 'margin-box']},775 '-webkit-appearance': {776 values: [777 'checkbox',778 'radio',779 'push-button',780 'square-button',781 'button',782 'inner-spin-button',783 'listbox',784 'media-slider',785 'media-sliderthumb',786 'media-volume-slider',787 'media-volume-sliderthumb',788 'menulist',789 'menulist-button',790 'meter',791 'progress-bar',792 'slider-horizontal',793 'slider-vertical',794 'sliderthumb-horizontal',795 'sliderthumb-vertical',796 'searchfield',797 'searchfield-cancel-button',798 'textfield',799 'textarea'800 ]801 },802 '-webkit-border-after': {803 values: [804 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'805 ]806 },807 '-webkit-border-after-style':808 {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},809 '-webkit-border-after-width': {values: ['medium', 'thick', 'thin']},810 '-webkit-border-before': {811 values: [812 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'813 ]814 },815 '-webkit-border-before-style':816 {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},817 '-webkit-border-before-width': {values: ['medium', 'thick', 'thin']},818 '-webkit-border-end': {819 values: [820 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'821 ]822 },823 '-webkit-border-end-style':824 {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},825 '-webkit-border-end-width': {values: ['medium', 'thick', 'thin']},826 '-webkit-border-start': {827 values: [828 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'829 ]830 },831 '-webkit-border-start-style':832 {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},833 '-webkit-border-start-width': {values: ['medium', 'thick', 'thin']},834 '-webkit-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},835 '-webkit-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},836 '-webkit-margin-collapse': {values: ['collapse', 'separate', 'discard']},837 '-webkit-mask-box-image': {values: ['repeat', 'stretch', 'space', 'round']},838 '-webkit-mask-box-image-repeat': {values: ['repeat', 'stretch', 'space', 'round']},839 '-webkit-mask-clip': {values: ['text', 'border', 'border-box', 'content', 'content-box', 'padding', 'padding-box']},840 '-webkit-mask-composite': {841 values: [842 'clear', 'copy', 'source-over', 'source-in', 'source-out', 'source-atop', 'destination-over', 'destination-in',843 'destination-out', 'destination-atop', 'xor', 'plus-lighter'844 ]845 },846 '-webkit-mask-image':847 {values: ['linear-gradient', 'radial-gradient', 'repeating-linear-gradient', 'repeating-radial-gradient', 'url']},848 '-webkit-mask-origin': {values: ['border', 'border-box', 'content', 'content-box', 'padding', 'padding-box']},849 '-webkit-mask-position': {values: ['top', 'bottom', 'left', 'right', 'center']},850 '-webkit-mask-position-x': {values: ['left', 'right', 'center']},851 '-webkit-mask-position-y': {values: ['top', 'bottom', 'center']},852 '-webkit-mask-repeat': {values: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round']},853 '-webkit-mask-size': {values: ['contain', 'cover']},854 '-webkit-max-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},855 '-webkit-max-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},856 '-webkit-min-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},857 '-webkit-min-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},858 '-webkit-perspective-origin-x': {values: ['left', 'right', 'center']},859 '-webkit-perspective-origin-y': {values: ['top', 'bottom', 'center']},860 '-webkit-text-decorations-in-effect': {values: ['blink', 'line-through', 'overline', 'underline']},861 '-webkit-text-stroke': {values: ['medium', 'thick', 'thin']},862 '-webkit-text-stroke-width': {values: ['medium', 'thick', 'thin']},863 '-webkit-transform-origin-x': {values: ['left', 'right', 'center']},864 '-webkit-transform-origin-y': {values: ['top', 'bottom', 'center']},865 'width': {values: ['-webkit-fill-available']}866};867// Weight of CSS properties based on their usage from https://www.chromestatus.com/metrics/css/popularity868const Weight = {869 'align-content': 57,870 'align-items': 129,871 'align-self': 55,872 'animation': 175,873 'animation-delay': 114,874 'animation-direction': 113,875 'animation-duration': 137,876 'animation-fill-mode': 132,877 'animation-iteration-count': 124,878 'animation-name': 139,879 'animation-play-state': 104,880 'animation-timing-function': 141,881 'backface-visibility': 123,882 'background': 260,883 'background-attachment': 119,884 'background-clip': 165,885 'background-color': 259,886 'background-image': 246,887 'background-origin': 107,888 'background-position': 237,889 'background-position-x': 108,890 'background-position-y': 93,891 'background-repeat': 234,892 'background-size': 203,893 'border': 263,894 'border-bottom': 233,895 'border-bottom-color': 190,896 'border-bottom-left-radius': 186,897 'border-bottom-right-radius': 185,898 'border-bottom-style': 150,899 'border-bottom-width': 179,900 'border-collapse': 209,901 'border-color': 226,902 'border-image': 89,903 'border-image-outset': 50,904 'border-image-repeat': 49,905 'border-image-slice': 58,906 'border-image-source': 32,907 'border-image-width': 52,908 'border-left': 221,909 'border-left-color': 174,910 'border-left-style': 142,911 'border-left-width': 172,912 'border-radius': 224,913 'border-right': 223,914 'border-right-color': 182,915 'border-right-style': 130,916 'border-right-width': 178,917 'border-spacing': 198,918 'border-style': 206,919 'border-top': 231,920 'border-top-color': 192,921 'border-top-left-radius': 187,922 'border-top-right-radius': 189,923 'border-top-style': 152,924 'border-top-width': 180,925 'border-width': 214,926 'bottom': 227,927 'box-shadow': 213,928 'box-sizing': 216,929 'caption-side': 96,930 'clear': 229,931 'clip': 173,932 'clip-rule': 5,933 'color': 256,934 'content': 219,935 'counter-increment': 111,936 'counter-reset': 110,937 'cursor': 250,938 'direction': 176,939 'display': 262,940 'empty-cells': 99,941 'fill': 140,942 'fill-opacity': 82,943 'fill-rule': 22,944 'filter': 160,945 'flex': 133,946 'flex-basis': 66,947 'flex-direction': 85,948 'flex-flow': 94,949 'flex-grow': 112,950 'flex-shrink': 61,951 'flex-wrap': 68,952 'float': 252,953 'font': 211,954 'font-family': 254,955 'font-kerning': 18,956 'font-size': 264,957 'font-stretch': 77,958 'font-style': 220,959 'font-variant': 161,960 'font-weight': 257,961 'height': 266,962 'image-rendering': 90,963 'justify-content': 127,964 'left': 248,965 'letter-spacing': 188,966 'line-height': 244,967 'list-style': 215,968 'list-style-image': 145,969 'list-style-position': 149,970 'list-style-type': 199,971 'margin': 267,972 'margin-bottom': 241,973 'margin-left': 243,974 'margin-right': 238,975 'margin-top': 253,976 'mask': 20,977 'max-height': 205,978 'max-width': 225,979 'min-height': 217,980 'min-width': 218,981 'object-fit': 33,982 'opacity': 251,983 'order': 117,984 'orphans': 146,985 'outline': 222,986 'outline-color': 153,987 'outline-offset': 147,988 'outline-style': 151,989 'outline-width': 148,990 'overflow': 255,991 'overflow-wrap': 105,992 'overflow-x': 184,993 'overflow-y': 196,994 'padding': 265,995 'padding-bottom': 230,996 'padding-left': 235,997 'padding-right': 232,998 'padding-top': 240,999 'page': 8,1000 'page-break-after': 120,1001 'page-break-before': 69,1002 'page-break-inside': 121,1003 'perspective': 92,1004 'perspective-origin': 103,1005 'pointer-events': 183,1006 'position': 261,1007 'quotes': 158,1008 'resize': 168,1009 'right': 245,1010 'shape-rendering': 38,1011 'size': 64,1012 'speak': 118,1013 'src': 170,1014 'stop-color': 42,1015 'stop-opacity': 31,1016 'stroke': 98,1017 'stroke-dasharray': 36,1018 'stroke-dashoffset': 3,1019 'stroke-linecap': 30,1020 'stroke-linejoin': 21,1021 'stroke-miterlimit': 12,1022 'stroke-opacity': 34,1023 'stroke-width': 87,1024 'table-layout': 171,1025 'tab-size': 46,1026 'text-align': 260,1027 'text-anchor': 35,1028 'text-decoration': 247,1029 'text-indent': 207,1030 'text-overflow': 204,1031 'text-rendering': 155,1032 'text-shadow': 208,1033 'text-transform': 202,1034 'top': 258,1035 'touch-action': 80,1036 'transform': 181,1037 'transform-origin': 162,1038 'transform-style': 86,1039 'transition': 193,1040 'transition-delay': 134,1041 'transition-duration': 135,1042 'transition-property': 131,1043 'transition-timing-function': 122,1044 'unicode-bidi': 156,1045 'unicode-range': 136,1046 'vertical-align': 236,1047 'visibility': 242,1048 '-webkit-appearance': 191,1049 '-webkit-backface-visibility': 154,1050 '-webkit-background-clip': 164,1051 '-webkit-background-origin': 40,1052 '-webkit-background-size': 163,1053 '-webkit-border-end': 9,1054 '-webkit-border-horizontal-spacing': 81,1055 '-webkit-border-image': 75,1056 '-webkit-border-radius': 212,1057 '-webkit-border-start': 10,1058 '-webkit-border-start-color': 16,1059 '-webkit-border-start-width': 13,1060 '-webkit-border-vertical-spacing': 43,1061 '-webkit-box-align': 101,1062 '-webkit-box-direction': 51,1063 '-webkit-box-flex': 128,1064 '-webkit-box-ordinal-group': 91,1065 '-webkit-box-orient': 144,1066 '-webkit-box-pack': 106,1067 '-webkit-box-reflect': 39,1068 '-webkit-box-shadow': 210,1069 '-webkit-column-break-inside': 60,1070 '-webkit-column-count': 84,1071 '-webkit-column-gap': 76,1072 '-webkit-column-rule': 25,1073 '-webkit-column-rule-color': 23,1074 '-webkit-columns': 44,1075 '-webkit-column-span': 29,1076 '-webkit-column-width': 47,1077 '-webkit-filter': 159,1078 '-webkit-font-feature-settings': 59,1079 '-webkit-font-smoothing': 177,1080 '-webkit-highlight': 1,1081 '-webkit-line-break': 45,1082 '-webkit-line-clamp': 126,1083 '-webkit-margin-after': 67,1084 '-webkit-margin-before': 70,1085 '-webkit-margin-collapse': 14,1086 '-webkit-margin-end': 65,1087 '-webkit-margin-start': 100,1088 '-webkit-margin-top-collapse': 78,1089 '-webkit-mask': 19,1090 '-webkit-mask-box-image': 72,1091 '-webkit-mask-image': 88,1092 '-webkit-mask-position': 54,1093 '-webkit-mask-repeat': 63,1094 '-webkit-mask-size': 79,1095 '-webkit-padding-after': 15,1096 '-webkit-padding-before': 28,1097 '-webkit-padding-end': 48,1098 '-webkit-padding-start': 73,1099 '-webkit-print-color-adjust': 83,1100 '-webkit-rtl-ordering': 7,1101 '-webkit-tap-highlight-color': 169,1102 '-webkit-text-emphasis-color': 11,1103 '-webkit-text-fill-color': 71,1104 '-webkit-text-security': 17,1105 '-webkit-text-stroke': 56,1106 '-webkit-text-stroke-color': 37,1107 '-webkit-text-stroke-width': 53,1108 '-webkit-user-drag': 95,1109 '-webkit-user-modify': 62,1110 '-webkit-user-select': 194,1111 '-webkit-writing-mode': 4,1112 'white-space': 228,1113 'widows': 115,1114 'width': 268,1115 'will-change': 74,1116 'word-break': 166,1117 'word-spacing': 157,1118 'word-wrap': 197,1119 'writing-mode': 41,1120 'z-index': 239,1121 'zoom': 2001122};1123// Common keywords to CSS properties1124const CommonKeywords = ['auto', 'none'];1125/**1126 * @typedef {{name: string, longhands: !Array.<string>, inherited: boolean, svg: boolean}}1127 */...
post.js
Source:post.js
1import React from 'react'2import {graphql} from 'gatsby'3import Img from 'gatsby-image'4import MDXRenderer from 'gatsby-plugin-mdx/mdx-renderer'5import isEmpty from 'lodash/isEmpty'6import SEO from 'components/seo'7import {css} from '@emotion/core'8import Container from 'components/container'9import Layout from 'components/layout'10import Share from 'components/share'11import SubscribeForm, {TinyLetterSubscribe} from 'components/forms/subscribe'12import BlogPostFooter from 'components/blog-post-footer'13import TestingCta from 'components/testing-cta'14import {15 WorkshopEventsProvider,16 useWorkshopEvents,17} from 'components/workshops/context'18import Markdown from 'react-markdown'19import {fonts} from '../lib/typography'20import config from '../../config/website'21import {bpMaxSM} from '../lib/breakpoints'22import get from 'lodash/get'23import intersection from 'lodash/intersection'24import flatMap from 'lodash/flatMap'25import first from 'lodash/first'26import UpcomingWorkshops from 'components/workshops/upcoming-workshops'27import titleCase from 'ap-style-title-case'28export default function PostPage(props) {29 return (30 <WorkshopEventsProvider>31 <Post {...props} />32 </WorkshopEventsProvider>33 )34}35function Post({data: {site, mdx}}) {36 const {37 isWriting,38 editLink,39 historyLink,40 title,41 date,42 slug,43 description,44 banner,45 bannerCredit,46 noFooter,47 keywords,48 } = mdx.fields49 const {eventsByKeywords, isLoading: isLoadingEvents} = useWorkshopEvents({50 keywords,51 })52 const commonKeyword = first(53 intersection(54 flatMap(eventsByKeywords, event => event.keywords),55 keywords,56 ),57 )58 const blogPostUrl = `${config.siteUrl}${slug}`59 return (60 <Layout61 site={site}62 frontmatter={mdx.fields}63 headerLink={isWriting ? '/writing/blog' : '/blog'}64 noFooter={noFooter}65 subscribeForm={isWriting ? <TinyLetterSubscribe /> : <SubscribeForm />}66 >67 <SEO68 frontmatter={mdx.fields}69 metaImage={get(mdx, 'fields.banner.childImageSharp.fluid.src')}70 isBlogPost71 />72 <article73 css={css`74 width: 100%;75 display: flex;76 twitter-widget {77 margin-left: auto;78 margin-right: auto;79 }80 `}81 >82 <Container83 css={css`84 padding-top: 20px;85 `}86 >87 <h188 css={css`89 text-align: center;90 margin-bottom: 20px;91 margin-top: 0;92 font-family: ${fonts.light};93 `}94 >95 {title}96 </h1>97 {banner && (98 <div99 css={css`100 text-align: center;101 p {102 margin-bottom: 0;103 }104 ${bpMaxSM} {105 padding: 0;106 }107 `}108 >109 <Img110 fluid={banner.childImageSharp.fluid}111 alt={site.siteMetadata.keywords.join(', ')}112 />113 {bannerCredit ? <Markdown>{bannerCredit}</Markdown> : null}114 </div>115 )}116 <br />117 {description ? <Markdown>{description}</Markdown> : null}118 <MDXRenderer>{mdx.body}</MDXRenderer>119 </Container>120 {/* <SubscribeForm /> */}121 </article>122 <Container noVerticalPadding>123 <a href={historyLink}>124 <time125 css={{126 textAlign: 'right',127 display: 'block',128 fontSize: '12px',129 marginBottom: '10px',130 }}131 title="Last Updated Date"132 >133 {date}134 </time>135 </a>136 </Container>137 <Container noVerticalPadding>138 <p css={{textAlign: 'right'}}>139 <a140 target="_blank"141 rel="noopener noreferrer"142 // using mobile.twitter.com because if people haven't upgraded143 // to the new experience, the regular URL wont work for them144 href={`https://mobile.twitter.com/search?q=${encodeURIComponent(145 blogPostUrl,146 )}`}147 >148 Discuss on Twitter149 </a>150 <span css={{marginLeft: 10, marginRight: 10}}>{` ⢠`}</span>151 <a target="_blank" rel="noopener noreferrer" href={editLink}>152 Edit post on GitHub153 </a>154 </p>155 </Container>156 <Container noVerticalPadding css={{marginBottom: 40}}>157 <Share158 url={blogPostUrl}159 title={title}160 twitterHandle={config.twitterHandle}161 />162 </Container>163 {isLoadingEvents ? (164 <div css={{textAlign: 'center'}}>165 loading relevant upcoming workshops...166 </div>167 ) : isEmpty(eventsByKeywords) ? null : (168 <div169 css={css`170 margin-top: 55px;171 display: flex;172 justify-content: center;173 `}174 >175 <UpcomingWorkshops176 headline={177 commonKeyword178 ? titleCase(`Upcoming ${commonKeyword} Workshops`)179 : 'Upcoming Workshops'180 }181 events={eventsByKeywords}182 />183 </div>184 )}185 {keywords.map(keyword => keyword.toLowerCase()).includes('testing') && (186 <TestingCta />187 )}188 <Container>189 <BlogPostFooter />190 </Container>191 </Layout>192 )193}194export const pageQuery = graphql`195 query($id: String!) {196 site {197 siteMetadata {198 keywords199 }200 }201 mdx(fields: {id: {eq: $id}}) {202 fields {203 editLink204 historyLink205 isWriting206 title207 date208 noFooter209 description210 plainTextDescription211 author212 banner {213 ...bannerImage720214 }215 bannerCredit216 slug217 keywords218 }219 body220 }221 }...
search.test.js
Source:search.test.js
1import { expect } from 'chai';2import gql from 'fake-tag';3import { describe, it } from 'mocha';4import { fakeCollective, randStr } from '../../../test-helpers/fake-data';5import * as utils from '../../../utils';6describe('server/graphql/v1/search', () => {7 let collectives, commonKeyword;8 before(async () => {9 await utils.resetTestDB();10 await utils.runSearchTsVectorMigration();11 commonKeyword = randStr();12 collectives = await Promise.all([13 fakeCollective({ name: randStr(), description: `A common keyword: ${commonKeyword}` }),14 fakeCollective({ name: randStr(), description: `A common keyword: ${commonKeyword}` }),15 fakeCollective({ name: randStr(), description: `A common keyword: ${commonKeyword}` }),16 ]);17 });18 it('returns list of CollectiveSearch types', async () => {19 const collectiveSearchQuery = gql`20 query CollectiveSearch($term: String!) {21 search(term: $term) {22 collectives {23 id24 }25 }26 }27 `;28 let result = await utils.graphqlQuery(collectiveSearchQuery, { term: commonKeyword });29 let returnedCollectives = result.data.search.collectives.map(c => c.id).sort();30 expect(returnedCollectives).to.deep.equal(collectives.map(c => c.id).sort());31 result = await utils.graphqlQuery(collectiveSearchQuery, { term: collectives[0].name });32 returnedCollectives = result.data.search.collectives;33 expect(returnedCollectives.length).to.equal(1);34 expect(returnedCollectives[0].id).to.equal(collectives[0].id);35 });36 it('accepts limit and offset arguments', async () => {37 const collectiveSearchQuery = gql`38 query CollectiveSearch($term: String!, $limit: Int!, $offset: Int!) {39 search(term: $term, limit: $limit, offset: $offset) {40 collectives {41 id42 name43 description44 }45 total46 limit47 offset48 }49 }50 `;51 const result = await utils.graphqlQuery(collectiveSearchQuery, { term: commonKeyword, limit: 2, offset: 0 });52 expect(result.data.search.collectives.length).to.equal(2);53 });...
compile_keywords.js
Source:compile_keywords.js
...61 // so you can force a score of 1 if you really insist62 if (providedScore) {63 return Number(providedScore);64 }65 return commonKeyword(keyword) ? 0 : 1;66}67/**68 * Determines if a given keyword is common or not69 *70 * @param {string} keyword */71function commonKeyword(keyword) {72 return COMMON_KEYWORDS.includes(keyword.toLowerCase());...
SavedNewsHeader.js
Source:SavedNewsHeader.js
...3import {CurrentUserContext} from '../../contexts/CurrentUserContext';4export default function SavedNewsHeader(props) {5 const User = React.useContext(CurrentUserContext);6 const cards = React.useContext(CurrentCardsContext);7 const keywords = commonKeyword(cards.map(card => card.keyword));8 9 function commonKeyword(keywords){ 10 return keywords.sort((a,b) =>11 keywords.filter(keyword => keyword===a).length12 - keywords.filter(keyword => keyword===b).length13 ).filter((v, i, a) => a.indexOf(v) === i).reverse();14 }15 return (16 <section className="SavedNewsHeader">17 <p className="SavedNewsHeader__caption">Saved articles</p>18 <h2 className="SavedNewsHeader__title">{User.name ? `${User.name}, you`: "You"} have {cards.length} saved articles</h2>19 <h3 className="SavedNewsHeader__keywords-title">{keywords.length > 0 && "By Keywords: "} 20 <span className="SavedNewsHeader__keywords-list"> 21 {keywords[0] && `${keywords[0]}`} 22 {keywords[1] && `, ${keywords[1]}`} 23 {keywords.length > 3 ? ` and ${keywords.length-2} others` : ...
Helpers.js
Source:Helpers.js
1import Helmet from "react-helmet"2import React from 'react';3import axios from "axios";4let Helpers = {5 axios: axios,6 baseUrl: 'http://192.168.1.23/Pangea-Pod/backend/api/',7 SEOtags: function (title = null, description = null, keyword = null) {8 let commonTitle = 'Home';9 let commonDescription = 'Common Description';10 let commonKeyword = 'Common Keyword';11 return (12 <Helmet>13 <meta charSet="utf-8"/>14 <title>{title ? title : commonTitle}</title>15 <meta name="Keywords" content={keyword ? keyword : commonKeyword}/>16 <meta name="Description" content={description ? description : commonDescription}/>17 </Helmet>18 );19 },20 setLocalStorageData: (key, data) => {21 localStorage.setItem(key, JSON.stringify(data));22 },23 getLocalStorageData: (key) => {24 return JSON.parse(localStorage.getItem(key));25 },26};...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.click('text=English');7 await page.click('#searchInput');8 await page.fill('#searchInput', 'playwright');9 await page.keyboard.press('Enter');10 await page.waitForSelector('text=Playwright is a Node.js library to automate Chromium, Firefox and WebKit with a single API.');11 await page.keyboard.press('Escape');12 await page.click('#searchInput');13 await page.fill('#searchInput', 'puppeteer');14 await page.keyboard.press('Enter');15 await page.waitForSelector('text=Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol.');16 await page.keyboard.press('Escape');17 await page.click('#searchInput');18 await page.fill('#searchInput', 'webdriver');19 await page.keyboard.press('Enter');20 await page.waitForSelector('text=WebDriver is an open source tool for automated testing of webapps across many browsers.');21 await page.keyboard.press('Escape');22 await page.click('#searchInput');23 await page.fill('#searchInput', 'cypress');24 await page.keyboard.press('Enter');25 await page.waitForSelector('text=Cypress is a front end testing tool built for the modern web.');26 await page.keyboard.press('Escape');27 await page.click('#searchInput');28 await page.fill('#searchInput', 'testcafe');29 await page.keyboard.press('Enter');30 await page.waitForSelector('text=TestCafe is a pure node.js end-to-end solution for testing web apps.');31 await page.keyboard.press('Escape');32 await page.click('#searchInput');33 await page.fill('#searchInput', 'playwright');34 await page.keyboard.press('Enter');35 await page.waitForSelector('text=Playwright is a Node.js library to automate Chromium, Firefox and WebKit with a single API.');36 await page.keyboard.press('Escape');37 await page.click('#searchInput');38 await page.fill('#searchInput', 'puppeteer');39 await page.keyboard.press('Enter');40 await page.waitForSelector('text=Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol.');
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const handle = await page.$('text=Get started');7 const element = handle.asElement();8 const text = await element.textContent();9 console.log(text);10 await browser.close();11})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const commonKeyword = await page.evaluateHandle(() => window.playwright.commonKeyword);7 await commonKeyword.evaluate(keyword => {8 });9 await browser.close();10})();11module.exports = {12 use: {13 playwrightInternalApi: {}14 }15};16const commonKeyword = await page.evaluateHandle(() => window.playwright.commonKeyword);17await commonKeyword.evaluate(keyword => {18});19const result = await commonKeyword.evaluateHandle(keyword => {20});21[MIT](./LICENSE)
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const keyword = await page.evaluate(() => window.chromium.commonKeyword());7 console.log(keyword);8 await browser.close();9})();10#### chromiumBrowser.version()11#### chromiumBrowser.userAgent()12#### chromiumBrowser.close()13#### chromiumBrowser.newContext([options])14 - `colorScheme` <"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. See [page.emulateMedia(options)](#pageemulatemedia
Using AI Code Generation
1const {commonKeyword} = require('@playwright/test');2const {chromium} = require('playwright');3const browser = await chromium.launch();4const context = await browser.newContext();5const page = await context.newPage();6await commonKeyword(page, 'fill', '#search_input_react', 'test');7await commonKeyword(page, 'press', '#search_input_react', 'Enter');8await commonKeyword(page, 'closePage', page);9await commonKeyword(page, 'closeContext', context);10await commonKeyword(page, 'closeBrowser', browser);11This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. 12When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. 13You can also take a look at the [contributing guide](
Using AI Code Generation
1const { commonKeyword } = require('@playwright/test');2const { test, expect } = commonKeyword();3test('My test', async ({ page }) => {4 const title = page.locator('text=Get started');5 expect(title).toBeVisible();6});
Using AI Code Generation
1const { test, expect } = require("@playwright/test");2test("test", async ({ page }) => {3 const internal = page.context()._browser._connection._channel;4 const keyword = await internal.commonKeyword("playwright");5 expect(keyword).toBe("Playwright");6});7#### method: `BrowserContext._connection()`8#### method: `BrowserContext._channel()`9#### method: `Browser._connection()`10#### method: `Browser._channel()`11#### method: `Connection._channel()`12#### method: `Channel._connection()`13#### method: `Channel._object()`14#### method: `Channel._objectId()`15#### method: `Channel._parent()`16#### method: `Channel._children()`17#### method: `Channel._apiName()`18#### method: `Channel._guid()`19#### method: `Channel._initializer()`20#### method: `Channel._dispose()`21#### method: `Channel._sendMessageToServer()`22#### method: `Channel._sendMayFailMessageToServer()`
Using AI Code Generation
1const { commonKeyword } = require('playwright');2const { assert } = require('chai');3(async () => {4 const { page } = await commonKeyword('launchBrowser');5 const title = await page.title();6 assert.strictEqual(title, 'Playwright');7 await commonKeyword('closeBrowser');8})();9const { chromium, firefox, webkit } = require('playwright');10(async () => {11 const browser = await chromium.launch();12 await browser.close();13})();14const { chromium } = require('playwright');15(async () => {16 const browser = await chromium.launch();17 const context = await browser.newContext();18 await context.close();19 await browser.close();20})();21const { chromium } = require('playwright');22(async () => {23 const browser = await chromium.launch();24 const context = await browser.newContext();25 const page = await context.newPage();26 await page.close();27 await context.close();28 await browser.close();29})();30const { chromium } = require('playwright');31(async () => {32 const browser = await chromium.launch();33 const context = await browser.newContext();34 const page = await context.newPage();35 await page.close();36 await context.close();37 await browser.close();38})();39const { chromium } = require('playwright');40(async () => {41 const browser = await chromium.launch();42 const context = await browser.newContext();
Using AI Code Generation
1const { commonKeyword } = require('@playwright/test');2const { test } = commonKeyword();3test('My test', async ({ page }) => {4});5### `test.describe()`6test.describe('My test suite', () => {7 test('My test', async ({ page }) => {8 });9});10### `test.fixme()`11test.fixme('My test', async ({ page }) => {12});13### `test.only()`14test.only('My test', async ({ page }) => {15});16### `test.beforeEach()`17test.beforeEach(async ({ page }) => {18});19test('My test', async ({ page }) => {20});21### `test.afterEach()`22test.afterEach(async ({ page }) => {23 await page.close();24});25test('My test', async ({ page }) => {26});27### `test.beforeAll()`28test.beforeAll(async ({ page }) => {29});30test('My test', async ({ page }) => {31});32### `test.afterAll()`33test.afterAll(async ({ page }) => {34 await page.close();
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!