[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Fwd: Our changes to KHTML and KJS
From:       Daniel Molkentin <molkentin () kde ! org>
Date:       2003-01-07 19:50:41
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



- ----------  On Tuesday 07 January 2003 20:31, Don Melton wrote:  ----------

Subject: Our changes to KHTML and KJS
Date: Tuesday 07 January 2003 20:31
From: Don Melton <gramps@apple.com>
To: Lars Knoll <knoll@kde.org>, Harri Porten <porten@kde.org>, Waldo Bastian 
<bastian@kde.org>, Dirk Mueller <mueller@kde.org>, Martin Jones 
<mjones@kde.org>, Torben Weis <weis@kde.org>, Antti Koivisto 
<koivisto@kde.org>, Simon Hausmann <hausmann@kde.org>, Daniel Molkentin 
<molkentin@kde.org>, Stefan Schimanski <schimmi@kde.org>, Peter Kelly 
<pmk@post.com>

Hi,

Here is the second email I promised which details our changes and
additions to KHTML and KJS which were done for Safari.

As it says on our open source web page at
http://developer.apple.com/darwin/projects/webcore/ the sources we will
post later today are based on KDE 3.0.2.  The best way to see every
change line by line is to diff against the originals.

- --
Don Melton
Safari Engineering Manager
Apple Computer

================
KHTMLView & Part
================

Changes to fix crashes:

- - Improved nil-document checking in some KHTMLPart code.

Changes for better compatibility with web sites:

- - Decode % sequences in javascript: URLs before executing them.
- - Parse http-refresh delays that are not integers.
- - Improved selection handling to deal with blocks inside inlines.
- - Make focus happen on mousedown, not on click. Matches behavior of
Gecko/WinIE.

Changes to improve speed:

- - Change code that checks QStrings for null to use isNull() rather than
== QString::null.
- - Change code that to use QConstString in more places, and to not use
it when the optimization doesn't work (because the QConstString gets
destroyed before the QString that's extracted from it).
- - For overflow:hidden elements, added support for scheduling a layout
that only repaints the overflow:hidden object.
- - Added support for unscheduling layouts and repaints.

Other changes:

- - Change reload logic to reload if the URL has a different anchor but
the rest is the same.
- - Don't add so extra newlines to when extracting selected text.
- - Fix problem where an empty user style sheet would cause the loader to
load each page itself as a style sheet, and where not enough style
recomputation was done when the user style sheet is changed.
- - Changed makeprop and makevalues scripts to write out const arrays.
- - Made many changes to connect with KWQ, using APPLE_CHANGES ifdef.
- - Changed namespace directive use in some .cpp files to avoid ambiguity
with out-of-namespace identifiers that exist in Apple headers.

===============================
Style System (css subdirectory)
===============================

- - Added support for an @-quirks directive, so that quirks mode rules
could be specified in html4.css.
- - Cleaned up @import rules to correctly indicate loading state and to
inherit parse mode from parent sheets.
- - Reworked font code to use 72 dpi and not 96 dpi (#ifdefed), and to
not apply scaling factors in some cases (since NSFont in Cocoa does
this in those cases).
- - Added support for a default fixed pitch size that is independent of
the serif/sans-serif size.
- - Made generic family checking and font name checking faster by
eliminating string compares. Also made pseudo checking faster by
caching information and avoiding string compares.
- - Added support for a __qem unit ("quirky" em) that is used to indicate
a margin that can be collapsed away in quirks mode (for the WinIE
margin collapsing quirk).
- - Added support for konq-body as a font family name. Used by tables to
reset to the body font in quirks mode.
- - Incorporated trunk patch for handling escaped characters in the
content property string. Fixed a bug in the trunk patch in order to
make this patch work with the CSS W3C page.
- - Improved error handling of badly named units (e.g., don't treat 10pts
as valid).
- - Treat overflow:scroll and auto like "hidden" for now until support
for those is added. This change at least makes the overflowed objects
have the correct dimensions (without screwing up the layout of the rest
of the page).
- - Removed konq-js-clip and cleaned up the clip code once that was
removed.

html4.css changes:
* Changed <body>'s margin from 10px to 8px.
* Added __qem units (for collapsing margins) to elements
* Removed konqblock
* Changed blockquote to have top/bottom margins and to no longer flow
arounds floats.
* Removed the 50px width/height on <object>s, so that they will
properly be 0 by 0 when no size is set.
* Changed <h1>-<h6> margins to match Gecko.
* Removed vertical-align: middle from <table>s rule, since inline
tables should default to baseline. Added middle alignment to the body,
head, and foot instead.
* Eliminated the overloading of padding and cellpadding, and stopped
the inheritance of padding from the parent in tables.
* Eliminated many of the <td> rules that weren't necessary and that
didn't work with center-aligned children.
* Added some basic support for children within <div align=right>
* Stopped <dl> from flowing around floats.
* Removed rules for <p> and <div> inside <li>s, since margin collapsing
now handles this.
* Added a bottom margin to <form>.
* Added margins to form controls (since Aqua controls look very bad
with no margins).
* Added margins to <pre> elements to match Gecko/WinIE.
* Fixed <big> and <small> to use larger and smaller instead of large
and small.
* Tweaked default link colors.
* Give floating images margins in quirks mode only (matches Gecko).

======================
DOM (dom subdirectory)
======================

- - Added support to DocumentStyle for a CSS3 proposal for selecting
stylesheet sets and for querying for the preferred stylesheet set.
- - On the appropriate event objects, added support for keyCode, pageX,
pageY, layerX, layerY and which.
- - Implemented support on Range for createContextualFragment.
- - Fixed doctype on Document to return null for HTML documents (only at
the DOM level). This is per spec.
- - Reworked DOMString for speed. Improved == operator. Inlined the
default constructor. Eliminated the "virtual" on the destructor.
- - Implemented setTitle on HTML documents.
- - Added support for x and y on images (Gecko compatibility).

========================
ECMA (ecma subdirectory)
========================

- - get/put use identifiers instead of UStrings (for speed)
- - Added code to deal with DOM objects to make sure they keep the same
wrapper for the lifetime of the document and don't leak when the
document goes away.
- - Implement support for offsetLeft/Top/Width/Height/Parent.
- - Added support for preferredStyleSheetSet, selectedStyleSheetSet.

- - Reworked scope chains.
- - Made sure that elements outside a <form> but still associated with
the form (e.g., malformed HTML) have the <form> on their scope chain.
- - Added support for keyCode, layerX, layerY, which, pageX, pageY to
events.
- - Pass document open calls with params to the window open.
- - Stubbed out captureEvents and releaseEvents. Not implemented yet.
- - Reworked <img> and <form> lookup on document to use a hash.
- - Fixed height and width on HTML documents to use the contentsHeight
and contentsWidth of the view.
- - Fixed a bug with URL resolution on documents.
- - Avoid setting of link colors to the same value by adding a check
(this was particularly slow in i-Bench).
- - Added support for x and y to image objects.
- - Added support for productSub (Gecko compatibility).
- - Improved our spoofing on various navigator object properties to work
based off current user agent (e.g., product).
- - Added support for createContextualFragment.
- - To the Window object, added screenLeft, screenTop, scrollX, scrollY,
releaseEvents, addEventListener, removeEventListener.

================================
HTML Content (html subdirectory)
================================

- - Lowered the tag priority of <a> and <font> to match other inlines
(like <i> and <span>).
- - Removed KONQBLOCK and the KONQBLOCK code completely. Elements are
still pulled outside of the table, but they are no longer wrapped in a
block, since that disrupts layout.
- - Allow ID_TEXT as a child in many places where it wasn't allowed
before. This is necessary to deal with whitespace changes (i.e., not
eliminating whitespace from the DOM).
- - Do not allow <object> and <embed> inside the <head>. Force them to be
pulled out into the <body>.
- - Make all inlines use tag_list_1 and be very lax about allowing blocks
inside them. With reworked block-inside-inline handling, this is now
acceptable.
- - Allow <center> inside <h1>-<h6>.
- - Change <ul> and <ol> to allow anything from tag_list_1. They behave
like other blocks now and allow content other than <li>s within them.
- - Accept <script> inside <map>.
- - Allow <form>s inside all table elements at all levels of the table.
- - Fix marginwidth and marginheight on the <body> to apply left/right
and top/bottom margins respectively.
- - Support arena allocation of RenderObjects for all of HTML.
- - Added checks to ensure RenderStyles don't leak (use proper
ref/deref). In some cases this involved restructuring the code in
various elements' attach methods.
- - Added URL security checking and depth of recursion defense to frames.
- - Made <div> use quirky -konq-center alignment for align values of
middle or center.
- - Added support for the align attribute to <p>.
- - Made redirects from within an onload handler avoid doing a
layout/render of the previous page (i-bench hack).
- - Changed the behavior of the strict/quirks mode function to more
closely match Gecko.
- - Added hashtables for named images and forms to the HTML document for
efficient lookup of those objects.
- - Fixed the definition of isInline in HTMLElement to make better
educated guesses when no render object exists yet. (Relevant because of
FOUC fixes).
- - Fixed a bug where dynamically changing the CLASS attribute didn't
work.
- - Implemented createContextualFragment and made setInnerHTML share the
same code.
- - Match Gecko's form submit behavior on "Enter" of using the first
successful submit button control as the submitted button.
- - Several APPLE_CHANGES related to form elements (for Cocoa, etc.).
- - Gave fieldset a render object so that child content would at least
render. (Still needs some default styling though.)
- - Made <input type=image> honor "width" attribute and call
updateFromElement.
- - Added type() implementations for all form control elements and their
sub-content (e.g., options).
- - Made alternate stylesheets work with .disabled.  Fleshed out support
for more capabilities of sheet selection and fixed numerous bugs in
alternate sheets.
- - Improved the <style> property to support more attributes (like TYPE).
- - Implemented delayed render object construction when stylesheets are
present. This prevents FOUC (flash of unstyled content) caused by
building render objects before stylesheets have loaded. Now render
object construction is delayed until all stylesheets have loaded.
- - Don't allow subsequent <title> elements after the first to change the
title.
- - Changed .width and .height on images to ensure that the image doesn't
need a layout before accessing the property.
- - Fixed a bug where <br clear> and <br clear=""> were treated as though
clear was specified. Other browsers treat it just like <br>.
- - Made <br> honor display: none.
- - Improved size number parsing for <font>.
- - Reworked the list-style-position quirk for orphaned <li>s to not use
CSS.
- - Added the ability to query HTMLCollections for names with
case-insensitivity.
- - Made <object>s that are images use RenderImage instead of making a
RenderPart. This allows them to size intrinsically.
- - Changed cellpadding on tables to not use the padding property. The
two can now be specified independently.
- - Fixed tables to reset the font to the <body> font and not to the
default document font in quirks mode.
- - Allow <form>s at all levels of a table, but demote them to leaves,
and make their subcontent into siblings of the <form>.
- - Added code to the parser to track discarded attributes and re-attach
them when error-handling. However, subsequent changes have rendered
this code obsolete so it really just needs to be removed.
- - Removed the blockBidi hack from the parser.
- - Removed KONQBLOCK from the parser and just made the content get
inserted directly before the table without being wrapped in a block.
- - Close a <caption> when illegal content is encountered inside it.
- - Implement the </p> quirk of treating stray </p>s like a <p>.
- - Detect malformed <form>s and mark the form as such so that its bottom
margin is ignored.
- - Tokenizer has a fixupChar (#ifdef APPLE_CHANGES) because we support
more unicode chars than Qt.
- - APPLE_CHANGES in tokenizer for script loading/execution.
- - Removed the automatic flattening of "XML-style" tags. It is incorrect
to treat <foo/> as if it closed in HTML and results in errors in
rendering on lots of Web sites. New behavior matches Gecko and WinIE.
- - Tokenizer no longer collapses/ignores whitespace.  The whitespace is
now added to the DOM (as it should be).

==============================================
XML Content and Generic DOM (xml subdirectory)
==============================================

- - Implemented layerX and layerY four mouse events.
- - Tweaked how key event type is decided.
- - Implemented createContextualFragment.
- - Updated DOMImplementation feature detection to support a version
value of "null".
- - Apple-specific change (#if APPLE_CHANGES) to use kwq signal/slot
mechanism.
- - Changed to use an arena for render objects
- - Changed how title-setting works (in #if APPLE_CHANGES)
- - Guard against style recal re-entrancy.
- - Changed standard font handling to be family-aware (should be in #if
APPLE_CHANGES)
- - Apple-specific change to make sure we don't have a selection and a
focused node at the same time (in APPLE_CHANGES)
- - Changed how styles are reprocessed after setting a user style sheet
(updateStyleSelector instead of recalcStyle)
- - Added support for http-equiv default-style
- - Parse refresh delay as a double not an int
- - Made various changes for layer awareness
- - Downcase attributes for HTML and XHTML
- - Corrected handling of preferred/alternate stylesheets so that the
right one is chose.
- - Implemented proposed DOM3 mechanism for selecting alternate style
sheets.
- - Changed stylesheet title handling
- - Apple-specific changes to support page cache
- - Added prototypes for many createInstance methods in #if APPLE_CHANGES
(implemented in kwq)
- - Apple-specific change to avoid crashing in NodeImpl::NodeImpl if
there is a view but the view has no part (is this possible any more?)
- - Process local events first for capture then for bubble
- - Make sure to close renderer even if it's created late (necessitated
by FOUC fixes)
- - Updated NodeImpl for render arenas.
- - Implemented NodeImpl::previousRenderer
- - Update insertBefore, replaceChild and appendChild to schedule a layout
- - Added support for malformed nodes and collapsing whitespace.
- - changed NodeImpl::restoreState to pass a string list, not just a
string
- - Added containsOnlyWhitespace method to DOMStringImpl
- - Added correct collapsing for all whitespace styles in
CharacterDataImpl
- - Apple-specific changes to eliminate use of i18n macro (in #if
APPLE_CHANGES)

===========================================
Rendering & Layout (rendering subdirectory)
===========================================

- - Reworked line breaking code (bidi.cpp) to properly deal with the CSS
whitespace property. Fixed numerous line breaking issues.
- - Added code to arena-allocate render objects and various objects
allocated by the render objects (like TextSlaves and BidiIterators).
- - Added support for the CSS2 font fallback mechanism.  Fonts can now
have family lists instead of supporting only a single family.
- - Made a few ifdefs in applet/object/plugin code for various
platform-specific issues.
- - Fixed background propagation on body/html/root to work correctly.
- - Improved repaint() and repaintRectangle() methods to repaint less.
- - Added support for render_layers, which are used to render positioned
and overflow:hidden objects. Layers enable more efficient and correct
event handling and painting. This implementation is roughly analogous
to the view system in Gecko. This system results in many bug fixes to
positioning, painting, event handling, and clipping.
- - Broke painting up into phases so that floats properly interleave
between the background of a block and inline content within a block.
Paint order now matches other browsers.  Renamed "print" methods to
"paint".
- - Fixed bugs with table cell background painting.
- - Fixed bugs with background positioning using percents.
- - Implemented support for min-width and max-width for basic normal flow
block elements.
- - Added some ifdefed hacks for Aqua form controls (since they have
built-in margins in the UA sheet).
- - Rewrote block inside inline handling to really work.  Inlines now
never morph into blocks.  The render tree can now handle splitting
inlines across multiple blocks using continuations to link the inlines
together.
- - Rewrote block layout of block children to support margin collapsing.
Also added rich support for WinIE margin collapsing quirks.
- - Removed an optimization that broke rendering when the <body> had
overflow.
- - Added a concept of overflow to render objects, so that their overflow
dimensions could be understood independent
of their constrained dimensions.
- - Rewrote block's calcMinMaxWidth as well as inline's calcMinMaxWidth.
RenderText has also had its minmax width computation rewritten.  All
are much more correct now when dealing with mixtures of white-space
types and with nested inline content.
- - Implemented support for the WinIE offsetWidth/Height/Top/Left/Parent
properties
- - Fixed bugs in the makeChildrenNonInline method that causes DHTML to
malfunction.
- - Rewrote nodeAtPoint to deal with blocks inside inlines properly and
to deal better with floating content.
- - Refactored form controls to ask the widgets for their intrinsic size.
  All ifdefed.
- - Added ifdefs for tweaks to frames and framesets.
- - Removed the 200x300 intrinsic default size of RenderParts and just
made them 0x0. This is ifdefed in case 0x0 is a problem for Qt
(although there are pages that broke because they expected the <object>
to have no size).
- - Made RenderImage's updateFromElement faster.
- - List items have been reworked to no longer make bullets float. All
bullets are now simply normal inline content. Added support for the
WinIE quirk that prevents nested list bullets from being on the same
line as ancestor lists (in strict mode this can be done). Matches
Gecko/WinIE.
- - Fixed bugs with the sizing/positioning of image bullets.
- - Implemented WinIE quirk of treating block and inline as table and
inline-table for <table> elements. Did the same quirk for <td>s as well.
- - Improved setLayouted to handle overflow:hidden content and only
schedule the layout for the hidden content (avoiding a full window
repaint).
- - Fixed several bugs with vertical-align.
- - Fixed layout error with replaced elements. Make sure they are
consistent regarding border/padding.
- - Added support for specifying whether repaints are immediate or not.
- - Made selection smarter.  Only repaints containing blocks rather than
repainting everything.  (Uses a redundant function though.  Need to
eliminate.)
- - Fixed a bug that caused color changes on links to do a full repaint.
- - Made inline tables work better.  Treat the inline table as a replaced
element and make it obey vertical position and baseline hints.
- - Fixed width error involving omission of borders.
- - Made percentage height tables work better (some bug fixes went in
after beta though).
- - Made tables with no cells or no rows but with specified widths and
heights actually work so that sites that use tables
as spacers don't misrender.
- - Improved table repainting.
- - Fixed bugs with nowrap on table cells.

=================
misc subdirectory
=================

- - Removed konqblock from tag list.
- - Added support for __qems (margin collapsing) to Length units.
- - Lots of APPLE_CHANGES to the loader for various features like
statistics and flushing.
- - Implemented size-adjusted and probability aware LRU in the loader
(LRU-SP) for improved handling of eviction from the loader cache.
- - Increased the size of the loader cache.
- - Improved color name lookup.

=============
kjs directory
=============

Changes made to improve speed and reduce memory use:

Note that changes to improve speed were driven by profiling and speed
testing, rather than intuition about what would help.

- - Put all identifiers in a global hash table so they can be compared
without comparing all the characters of the strings.
- - Store hash value in each string when it's computed so you don't have
to compute it more than once for the same string.
- - Eliminate the arguments stack in function objects, instead get the
arguments from the activation objects in the context only when the
arguments property is requested.
- - Change activation objects to create arguments object only when the
arguments property is requested.
- - Use a hash table for each object's property map rather that a
balanced tree.
- - Allocate ContextImp objects on the stack instead of the heap.
- - Use strtoll instead of strtol to parse integers.
- - Don't store the length of parameters in function objects, instead
compute it when the length property is requested.
- - Create a new class to hold scope chains, called ScopeChain, and use
it instead of a List. Since the class causes the tail of the scope
chain to be shared, it eliminates a lot of list manipulation.
- - Simplify parameter iteration code, removing an extra level of pointer
dereferencing.
- - Change array objects to use vector instead of storing array elements
in the property map, for speed when dealing with small contiguous
arrays.
- - Store property names used in if statements in global variables to
avoid creating and destroying strings each time.
- - Change array object sorting to use the C library's qsort function
rather than a selection sort, but keep the selection sort for non-array
objects, since it's not straightforward to use the C library to sort
them. Also reuse the same arguments list each time.
- - Change much code to minimize creating/destroying Value and Object
smart pointers to reduce the time spent in ref and deref.
- - Change much code to use const X & in places where we were copying
objects before, mostly Value and Object smart pointers.
- - Add a code path for properties that are integers so that they don't
get turned into strings. This makes it so that array indexes aren't
turned into strings and back again.
- - Use putDirect in places where it's safe to avoid creating smart
pointer wrappers and to skip some code.
- - Change constructors for Imp classes to take the prototype as an
ObjectImp * instead of an Object & to reduce the time spent in ref and
deref.
- - Rewrite garbage collector:
   1) Store small objects in the garbage collector blocks to avoid
malloc/free (objects that exceed the cell size are still allocated
directly with malloc/free, but there are very few such objects).
   2) Maintain a free list in each block to make it cheap to find the
next free object.
   3) Change algorithm to do only two passes over the heap instead of
five and made related changes to the loops to reduce flat time; this
allowed us to remove the VI_DESTRUCTED flag.
   4) Keep around a few spare free blocks so we don't allocate and
deallocate blocks so much.
   6) Bail out while sweeping a block when we find all the live cells
based on the used count; this makes almost-empty blocks less expensive.
   7) Collect every 1000 allocations -- the old policy would make
collection more and more rare as the number of live objects increased,
which lets memory use get huge and makes each collection slow.
- - Add an optimization where most integers can be stored in Imp
pointers, instead of requiring a separate NumberImp object for each.
This greatly reduces the number of objects the garbage collector needs
to deal with.
- - Change Reference, Completion, and List objects to no longer be
garbage collected JavaScript objects. Since these are internal details
of the interpreter implementation, they don't have to be ObjectImp
subclasses. This greatly reduces the number of objects the garbage
collector needs to deal with.
- - Do more inlining.
- - Make the globalObject() function return a reference to avoid some
ref/unref.
- - Remove the ExecStateImp class, putting the state right into ExecState
(poorer encapsulation, but better speed).
- - Change the Lookup class so that you can look up things without
allocating a block on the heap and narrowing the 16-bit characters to
8-bit characters.
- - Change the List implementation to use a vector rather than a linked
list, and a pool of fixed-size lists for quick allocation and
deallocation.
- - Make resizing strings faster by storing capacity separate from length
and sizing up in chunks.
- - Make concatenating strings more efficient by doing it in a
constructor.
- - Make converting integers to strings faster by doing it without
calling sprintf.
- - Give the static buffer used by UString::ascii() a minimum size so we
don't have to resize it often.
- - Make many other speed improvements in the implementation of various
UString functions.

Changes made to increase compatibility with web sites:

- - Do some bug fixes for to the handling of NaN and invalid dates in
date object functions.
- - Fix bug where it was calling mktime instead of timegm when
constructing a date object with the UTC function.
- - Fix error checking when parsing numbers in dates, fixed a small bug
in the month name parsing, allow the year to be misplaced and still
parse, and interpret missing time zone as the current time zone as
other browsers do.
- - Don't clobber existing values when a variable is declared;
specifically, redeclaring function parameters doesn't hide them or
reset them to Undefined().
- - Fix infinite loop when replacing a regular expression that matches
empty text with a string.
- - Fix double formatting to match what the ECMA spec. requires.
- - Eliminate virtual destructor in class Object, since a smart pointer
is not used in a polymorphic way and thus doesn't need a virtual
destructor.
- - Incorporate David M. Gay's number conversion library to ensure
numbers like 9.2 get formatted as 9.2 instead of 9.19999999999999999
and use it correctly to make double formatting match what the ECMA
specifies.

Changes made to reduce stack use:

- - Change the node classes to reverse the linked lists they build and
use iteration rather than recursion to deal with things like elements
in arrays and statements in source code blocks.
- - Remove the SourceElementNode class altogether and just use a
StatementNode.
- - Change the parser to count "elisions" in arrays without creating
separate node objects for each, and later recursing to count them.

Other changes:

- - Change FunctionBodyNode to inherit from BlockNode to save code.
- - Add locking so KJS can be used on multiple threads, as long as it's a
separate interpreter on each thread. (In APPLE_CHANGES.)
- - Change the library to not use the C standard date and time functions
to work around a speed problem in the OS X 10.2 version. (In
APPLE_CHANGES.)
- - Move ArrayInstanceImp, Completion, and List to their own header files.
- - Add some additional statistics to the garbage collector for debugging.
- - Add a debug-only kjsprint function that logs to stdout.
- - Add a debug-only printf when an exception is not caught.
- - Make some small fixes to compile with high warning settings (-Werror
- -Wall -W -Wcast-align -Wchar-subscripts -Wformat-security
- -Wmissing-format-attribute -Wmissing-prototypes -Wpointer-arith
- -Wwrite-strings -Wno-format-y2k -Wno-unused-parameter).

- -------------------------------------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQE+Gy+cu1Wkf8kBwz4RAsSEAKCmLQfbZmS9bEsqSiekatd5UA9BdwCfXBc1
0tZbBZ/N7s/Tl1Vq3lB962g=
=nl7B
-----END PGP SIGNATURE-----

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic